package xyz.scootaloo.kami.server

import io.vertx.core.Future
import io.vertx.core.Verticle
import io.vertx.core.Vertx
import io.vertx.core.impl.cpu.CpuCoreSensor
import io.vertx.kotlin.core.deploymentOptionsOf
import io.vertx.kotlin.core.vertxOptionsOf
import xyz.scootaloo.kami.server.verticle.vertx

/**
 * @author flutterdash@qq.com
 * @since 2022/3/26 11:54
 */
class KamiCloud {

    init {
        System.setProperty("log4j.skipJansi", "false") // 启用彩色日志
    }

    fun start(): Future<Unit> {
        return MainVerticle.deploy()
    }

    fun shutdown(): Future<Unit> {
        return MainVerticle.undeploy().onSuccess {
            vertx.close()
        }
    }

    private fun Verticle.deploy(): Future<Unit> {
        return prepareDefVertxRef()
            .deployVerticle(this, deploymentOptionsOf(worker = true))
            .transform { done ->
                if (done.succeeded())
                    Future.succeededFuture()
                else
                    Future.failedFuture(done.cause())
            }
    }

    private fun Verticle.undeploy(): Future<Unit> {
        return vertx.undeploy(MainVerticle.deploymentId)
            .transform { done ->
            if (done.succeeded())
                Future.succeededFuture()
            else
                Future.failedFuture(done.cause())
        }
    }

    private fun prepareDefVertxRef(): Vertx {
        return Vertx.vertx(vertxDefOptions())
    }

    private fun vertxDefOptions() = vertxOptionsOf(
        eventLoopPoolSize = cpuCoreSensorCount(),
        workerPoolSize = cpuCoreSensorCount() * 1,
        internalBlockingPoolSize = cpuCoreSensorCount() * 2
    )

    private fun cpuCoreSensorCount(): Int {
        return CpuCoreSensor.availableProcessors()
    }

    companion object {
        @JvmStatic
        fun start() {
            KamiCloud().start()
        }

        @JvmStatic
        fun main(args: Array<String>) {
            start()
        }
    }

}